#include "semantic.h"
//necessary
#include "NodeType.h"
#include "compileError.h"


void sem(/*in*/ PSyntaxNode pnode){
	/*switch (pnode->type){
	case NODE_GROUP_LABEL_FILE:{
		tmp=pnode->child;
		do {
			sem(tmp);
		} while ((tmp=tmp->brother)!=NULL);
		break;
	}
	case NODE_GROUP_LABELS_DEFINITION:{
		//if (pnode->child
		break;
	}
	case NODE_ID:{
		break;
	}
	case NODE_PUBLIC:{
		break;
	}
	case NODE_PACKAGE: {
		break;
	}
	}*/
}


void sym(PSyntaxNode pnode,PlabelHashTable labeltable,PclassHashTable classtable){
	PSyntaxNode tmp;
	//printSyntaxNode(stdout,pnode);
	switch (pnode->type){
	case NODE_PROGRAM:
		sym(pnode->child,labeltable,classtable);
		break;
	case NODE_CLASS_FILE					:
		//TODO
	case NODE_GROUP_LABEL_FILE:
		sym(pnode->child,labeltable,classtable);
		break;
	case NODE_GROUP_LABELS_DEFINITION_SECTOR:
		tmp=pnode->child;
		while(tmp!=NULL){//analyze all the label definitions
			sym(tmp,labeltable,classtable);
			tmp=tmp->brother;
		}
		break;
	case NODE_GROUP_LABELS_DEFINITION_LIST:
		//<NONE>
		break;
	case NODE_GROUP_LABELS_DEFINITION:
		tmp=pnode->child;
		//check wether the modifier is package or public
		if ((tmp->type!=NODE_PACKAGE) && (tmp->type!=NODE_PUBLIC)){
			fprintf(stderr,ERROR_SEM_01);
			exit(ERROR_SEM_01_EV);
		}
		//TODO to improve performance you might consider erasing LabelClassType and using the type of the pnode instead
		LabelClassType type=tmp->type==NODE_PACKAGE?LABEL_PACKAGE:LABEL_PUBLIC;
		//add the label to the symbol table
		while ((tmp=tmp->brother)!=NULL){
			//check wether the label is already present
			if (findLabelInHashTable(labeltable,tmp->value.sval)!=NULL){
				fprintf(stderr,ERROR_SEM_02,tmp->value.sval);
				exit(ERROR_SEM_02_EV);
			}
			addLabelInHashTable(labeltable,initLabel(tmp->value.sval,type));
		}
		break;
	case NODE_ID_LIST						:
		//<NONE>
	case NODE_MODIFIER_SECTOR				:

	case NODE_MODIFIER_LIST					:

	case NODE_MODIFIER_ELEMENT				:

	case NODE_MODE_POLICIES_SECTOR			:

	case NODE_READ_POLICIES					:

	case NODE_WRITE_POLICIES				:

	case NODE_ACCESS_GROUP_LIST				:
	case NODE_ACCESS_GROUP_ELEMENT			:
	case NODE_TYPE							:
	case NODE_SIMPLE_TYPE					:
	case NODE_CLASS_TYPE						:
	case NODE_ARRAY_TYPE						:
	case NODE_REQUIRE_SECTOR					:
	case NODE_REQUIRE_LIST					:
	case NODE_REQUIRE_ELEMENT				:
	case NODE_FIELD_DECLARATION_SECTOR		:
	case NODE_FIELD_LIST						:
	case NODE_FIELD_ELEMENT					:
	case NODE_METHOD_DECLARATION_SECTOR		:
	case NODE_METHOD_LIST					:
	case NODE_METHOD							:
	case NODE_RETURN_TYPE					:
	case NODE_FORMAL_PARAM_DECLARATION_SECTOR:
	case NODE_FORMAL_PARAM_DECLARATION_LIST	:
	case NODE_FORMAL_PARAM_DECLARATION		:
	case NODE_ACTUAL_PARAM_SECTOR			:
	case NODE_ACTUAL_PARAM_LIST				:
	case NODE_LEFT_HAND_SIDE					:
	case NODE_FIELD_VAR						:
	case NODE_PROCEDURE_CALL					:
	case NODE_ARRAY_VAR						:
	case NODE_NEW_INSTANCE					:
	case NODE_INSTANCE_MODE					:
	case NODE_BRACES_LIST					:
	case NODE_BRACES_ELEMENT					:
	case NODE_EXPR							:
	case NODE_INNER_EXPR						:
	case NODE_COMPARE_EXPR					:
	case NODE_COMPARE_OPERATOR				:
	case NODE_LOGIC_EXPR						:
	case NODE_LOGIC_OPERATOR					:
	case NODE_MATH_EXPR_1					:
	case NODE_MATH_EXPR_2					:
	case NODE_TERM_EXPR						:
	case NODE_CONSTANT						:
	case NODE_CLASS_DEFINITION				:
	case NODE_ADDITIONAL_CLAUSES_SECTOR		:
	case NODE_ADDITIONAL_CLAUSE_LIST			:
	case NODE_ADDITIONAL_CLAUSE				:
	case NODE_EXTENDS_CLAUSE					:
	case NODE_GROUP_MEMBER_CLAUSE			:
	case NODE_STAT_SECTOR					:
	case NODE_STAT_LIST						:
	case NODE_STAT							:
	case NODE_LOCAL_VARIABLE					:
	case NODE_ASSIGN_STAT					:
	case NODE_WHILE_STAT						:
	case NODE_DO_WHILE_STAT					:
	case NODE_FOR_STAT						:
	case NODE_IF_STAT						:
	case NODE_ELSIF_ELSE_STAT_SECTOR			:
	case NODE_ELSIF_ELSE_STAT_LIST			:
	case NODE_ELSIF_STAT						:
	case NODE_ELSE_STAT						:
	case NODE_SWITCH_STAT					:
	case NODE_SWITCH_LIST					:
	case NODE_CASE_CLAUSE_LIST				:
	case NODE_CASE_CLAUSE					:
	case NODE_DEFAULT_CLAUSE					:
	case NODE_CONTINUE_STAT					:
	case NODE_BREAK_STAT						:
	case NODE_RETURN_STAT					:
		//value focus nodes
	case NODE_CHARCONST						:
	case NODE_INTCONST						:
	case NODE_FLOATCONST						:
	case NODE_STRINGCONST					:
	case NODE_BOOLCONST						:
	case NODE_ID:
		break;
	case NODE_INT_TYPE						:
	case NODE_CHAR_TYPE						:
	case NODE_FLOAT_TYPE						:
	case NODE_STRING_TYPE					:
	case NODE_BOOL_TYPE						:
		//modifier nodes
	case NODE_PUBLIC							:
	case NODE_PACKAGE						:
	case NODE_ALL							:
	case NODE_ONLYME							:
	case NODE_CHILDREN						:
	case NODE_ABSTRACT						:
	case NODE_CONST							:
	case NODE_STATIC							:
	case NODE_REFERENCE						:
	case NODE_VALUE							:
	case NODE_VOID							:
	case NODE_REAL							:
	case NODE_COPY							:
	case NODE_THIS							:
	case NODE_BREAK							:
	case NODE_RETURN							:
	case NODE_CONTINUE						:
		//operation nodes
	case NODE_PLUS							:
	case NODE_MINUS							:
	case NODE_TIMES							:
	case NODE_DIVISION						:
	case NODE_REMAINDER						:
	case NODE_OPPOSITE						:
	case NODE_NEGATIVE						:
	case NODE_AND							:
	case NODE_OR								:
	case NODE_LEQ							:
	case NODE_LT								:
	case NODE_GEQ							:
	case NODE_GT								:
	case NODE_EQ								:
	case NODE_NE								: {
		break;
	}
	}
}


/*PclassHT sym(PSyntaxNode pnode){
	PclassHT result;
	initClassHT(&result);

}*/
